home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 014 / libtools.arc / SAMPLE.AQM / SAMPLE.ASM
Encoding:
Assembly Source File  |  1984-04-08  |  8.9 KB  |  276 lines

  1. PAGE 60,132
  2. TITLE MAIN -- SAMPLE ASSEMBLER ROUTINE TO ADD 3 NUMBERS (ADDOUT.ASM)
  3. COMMENT *   Written  by  Larry Jordan, 1983 *
  4.  
  5. .RADIX    16                      ;DEFAULT NUMBERS ARE HEX
  6.  
  7. SUBTTL DEFINITIONS OF MACROS
  8.     PAGE
  9. SCROLL    MACRO
  10.     MOV    AX,600H     ;AH=6 Requests scroll, AL=0 means entire wind
  11.     BIOSCALL        ;Invoke BIOS to scroll the window
  12.     ENDM
  13. ;
  14. KEYBOARD MACRO
  15.     MOV    AH,10D        ;Function selected = read keyboard
  16.     DOSCALL         ;Invoke DOS to read keyboard
  17.     ENDM
  18. ;
  19. LOCATE    MACRO
  20.     MOV    AH,2        ;Function selected = locate
  21.     BIOSCALL        ;Invoke BIOS to move cursor
  22.     ENDM
  23.     PAGE
  24. DISPLAY MACRO    TEXT
  25.     MOV    DX,OFFSET TEXT    ;Point to message to print
  26.     MOV    AH,9        ;Function selected = console output
  27.     DOSCALL         ;Invoke DOS to display message
  28.     ENDM
  29. ;
  30. DOSCALL MACRO
  31.     INT    21H        ;Request DOS service, id in AH
  32.     ENDM
  33. ;
  34. BIOSCALL MACRO
  35.     INT    10H        ;Request BIOS service, id in AH
  36.     ENDM
  37.  
  38.  
  39. SUBTTL DESCRIPTION OF THE STACK SEGMENT
  40.     PAGE
  41. STACKSEG  SEGMENT PARA STACK 'STACK'
  42.  
  43. ; Initial contents of the stack area may be anything.  Use of the
  44. ; word 'STACK   ' here does show up nicely when using DEBUG to look
  45. ; at memory.  By setting the stack to some known original value, it
  46. ; is possible to look at the stack area using DEBUG after the run to
  47. ; see just how much of the area was actually used.
  48.  
  49.        DW       100 DUP(?)
  50. STACKSEG   ENDS
  51.  
  52.  
  53. SUBTTL DESCRIPTION OF THE DATA WORKAREA
  54.     PAGE
  55. DATASEG SEGMENT PARA PUBLIC 'DATA'
  56.  
  57.          FIRST_NUM         DW    1,2,3
  58.          STORE_AL         DB    0
  59.          STORE_AH         DB    0
  60.          STORE_AX         DW    0
  61.          LOW_NIBBLE_AL   DB    0
  62.          HI_NIBBLE_AL    DB    0
  63.          LOW_NIBBLE_AH   DB    0
  64.          HI_NIBBLE_AH    DB    0
  65.          REPORT_1         DB    'The '
  66.          VARIABLE_1      DW    0
  67.                  DB    ' total is = '
  68.          VARIABLE_2      DB    0
  69.          VARIABLE_3      DB    0
  70.          VARIABLE_4      DB    0
  71.          VARIABLE_5      DB    0
  72.                  DB    ' H.',0AH,0DH
  73. DATASEG ENDS
  74.  
  75.  
  76. SUBTTL ESTABLISH DOS INTERFACES
  77.        PAGE
  78.  
  79. CODESEG SEGMENT PARA PUBLIC 'CODE'           ;SET UP CODE SEGMENT
  80.  
  81. MAIN PROC FAR                     ;SET UP 2 WORD STACK PUSH/POP
  82.  
  83. ASSUME CS:CODESEG,DS:DATASEG,ES:NOTHING      ;GIVE SEGMENTS NAMES
  84.  
  85. TOTAL_NUM    EQU     03              ;TOTAL NUMBER TO BE ADDED EQUAL 10
  86. EFFZERO      EQU     0F0
  87. ZEROEFF      EQU     0F
  88.  
  89. ;
  90. ;    At entry:
  91. ;    CS=Addr of entry point
  92. ;    IP=0, offset to entry point
  93. ;    SS=Segment address of stack segment
  94. ;    SP=200H, offset into stack of top of stack
  95. ;    DS=Segment address of Program Segment Prefix area
  96. ;    ES=Same as DS
  97. ;
  98. ;    At exit:
  99. ;    It is the user's responsibility to ensure that:
  100. ;    CS=Segment address of Program Segment Prefix area,
  101. ;        originally in DS or ES.
  102. ;    SS=Same value as at entry
  103. ;    (Other regs may be destroyed.)
  104.  
  105. SUBTTL ESTABLISH ENTRY LINKAGE FROM DOS
  106.     PAGE
  107. ;    Set up the stack to contain the proper values so this
  108. ;    program can return to DOS.
  109. ;
  110.     PUSH    DS        ;Set DOS return segment addr to stack
  111.     SUB    AX,AX        ;Clear a reg
  112.     PUSH    AX        ;Put zero return addr to stack
  113. ;
  114. ;    Establish addressability for the data segment.
  115. ;
  116.     GO: MOV    AX,DATASEG    ;Get location of DATA workarea
  117.     MOV    DS,AX        ;Set segreg base of data workarea
  118. ;
  119. ;    (Extra Segment, ES segreg, not used)
  120. ;
  121.     XOR    SI,SI                ;CLEAR THE SOURCE INDEX
  122.     MOV    CX,TOTAL_NUM            ;INITILIZE LOOP COUNT
  123.     XOR    AX,AX                ;CLEAR ACCUMULATOR REGISTER
  124. ;
  125. ;    Do the addition of 10 numbers
  126. ;
  127.   LOOP: ADD    AX,FIRST_NUM[SI]         ;ADD NUMBER IN ADDRESS FIRST_NUM
  128.                         ;+ THE CONTENTS OF SI TO SUM
  129.     ADD    SI,02                ;INC INDEX BY 2 BYTES (WORD)
  130.     DEC    CX                ;DECREMENT THE LOOP COUNT REGISTER
  131.     JNZ    LOOP                ;CONTINUE LOOP IF CX NOT EQU 0
  132.     MOV    WORD PTR [STORE_AX],AX        ;MOVE ACCUMULATOR TO STORAGE
  133.  
  134. SUBTTL CLEAR THE SCREEN, PUT CURSOR AT TOP LEFT CORNER THEN PRINT RESULTS
  135.     PAGE
  136.     CALL    CLS        ;Call the clear screen routine
  137.     MOV    DX,0        ;DH=0, DL=0 (DH=Row,DL=Column)
  138.     MOV    BH,0        ;Screen # to use
  139.                 ;Call to BIOS: This is where
  140.     LOCATE            ;the computer will do the locate
  141.  
  142.  
  143.    CRT:  MOV    WORD PTR [VARIABLE_1],'XA'   ;START VALUE PROCESS
  144.      MOV    AX,WORD PTR [STORE_AX]         ;MOVE ACCUM VALUE BACK INTO AX
  145.      CALL    PROCESS_1             ;PRINT THE CONTENTS OF AX
  146.  
  147. SUBTTL RESTORE THE ENTRY CONDITIONS, RETURN TO DOS
  148.     PAGE
  149. ;    For the RETURN to execute properly, the stack
  150. ;    must be restored to the point where only the
  151. ;    return parameters are still on the stack.
  152. ;    Any values saved on the stack must be popped
  153. ;    off to restore segregs to the value expected
  154. ;    by DOS.
  155. ;
  156.     RET            ;Far return to DOS
  157. ;
  158. ;    This changes the CS to point to the Program Segment Prefix
  159. ;    area, whose address was originally passed in DS.
  160. ;    The IP is set to zero.    At offset of zero in the
  161. ;    Program Header is an INT 20H instruction which
  162. ;    returns control to DOS.
  163. ;
  164. ;    RETURN TO DOS CONTROL BY POPPING 2 WORD CS:IP ADDRESS FROM STACK
  165. ;    THAT IS ACTUALLY THE DOS INT 20 LEFT AT THE TOP OF PROGRAM PREFIX
  166. ;    AREA - DS LOCATION CODE START
  167.  
  168. MAIN ENDP
  169.  
  170.  
  171. SUBTTL COMMON CODE LOCAL SUBROUTINE, CLEARS SCREEN
  172.     PAGE
  173. ;    This routine is called several times throughout the program.
  174. ;    It uses the BIOS call to do a scroll.  To do this, AH must be
  175. ;    6 (Routine number), AL must be zero (Zero signifies to clear
  176. ;    the window), CX must point to the upper left corner of the
  177. ;    window, (here we use 0,0), and DX must point to the lower
  178. ;    right corner (we use 24,79).  Also, BH must be the attribute to
  179. ;    use in the clear screen. We will use 7, the normal attribute.
  180. ;
  181. CLS    PROC    NEAR
  182.     MOV    CX,0        ;Upper left coord (0,0)
  183.     MOV    DX,2479H    ;Bottom right position
  184.     MOV    BH,7        ;Normal attribute for CLS
  185.     SCROLL            ;Clear entire screen
  186.     RET            ;Return to caller
  187. CLS    ENDP
  188.  
  189.  
  190. PROCESS_1 PROC NEAR
  191.      MOV    BYTE PTR [STORE_AL],AL         ;STORE LOW BYTE OF ACCUMULATOR
  192.      MOV    BYTE PTR [STORE_AH],AH         ;DITTO FOR HI BYTE
  193.      CALL    HEXDEC                 ;CONVERT ACCUMULATOR VALUE TO ASCII
  194.      CALL    MOVE_TO_VARIABLES         ;MOVE ASCII TO STRINGS
  195.      XOR    AX,AX                 ;CLEAR AX REGISTER
  196.      CALL    SEND_REPORT             ;PRINT ACCUMULATOR CONTENTS
  197.      RET                     ;RETURN TO CRT CALLER
  198. PROCESS_1 ENDP
  199.  
  200. MOVE_TO_VARIABLES PROC NEAR
  201.     MOV    AL,BYTE PTR [LOW_NIBBLE_AL]     ;LOW NIBBLE OF AL TO AL
  202.     MOV    BYTE PTR [VARIABLE_5],AL     ;AL TO LOWNIB POS IN STRING
  203.     MOV    AL,BYTE PTR [HI_NIBBLE_AL]     ;HI NIBBLE OF AL TO AL
  204.     MOV    BYTE PTR [VARIABLE_4],AL     ;AL TO HINIB POS IN STRING
  205.     MOV    AL,BYTE PTR [LOW_NIBBLE_AH]     ;LOW NIBBLE OF AH TO AL
  206.     MOV    BYTE PTR [VARIABLE_3],AL     ;AL TO LOWNIB FOR AH POS
  207.     MOV    AL,BYTE PTR [HI_NIBBLE_AH]     ;HI NIBBLE OF AH TO AL
  208.     MOV    BYTE PTR [VARIABLE_2],AL     ;AL TO HINIB FOR AH POS
  209.     RET                     ;AND RETURN TO CALLER
  210. MOVE_TO_VARIABLES ENDP
  211.  
  212. HEXDEC PROC NEAR
  213.     XOR    AX,AX                 ;CLEAR AX REG
  214.     MOV    AL,BYTE PTR [STORE_AL]         ;GET VALUE
  215.     AND    AL,ZEROEFF             ;MASK OFF HI NIBBLE
  216.     CALL    PROC_LOW_NIBBLE          ;AND GET THE ASCII FOR IT
  217.     MOV    BYTE PTR [LOW_NIBBLE_AL],AL     ;THEN MOVE THAT TO STORAGE
  218.     XOR    AX,AX                 ;CLEAR THE AX REG
  219.     MOV    AL,BYTE PTR [STORE_AL]         ;GET THE VALUE AGAIN
  220.     CALL    PROC_HI_NIBBLE             ;TO PROCESS THE HIGH NIBBLE
  221.     CALL    PROC_LOW_NIBBLE          ;THEN TO THE SAME JOB AGAIN
  222.     MOV    BYTE PTR [HI_NIBBLE_AL],AL     ;MOVE IT TO STORAGE
  223.     XOR    AX,AX                 ;CLEAR THE AX REGISTER AGAIN
  224.     MOV    AL,BYTE PTR [STORE_AH]         ;MOVE THE AH REG VALUE INTO AL
  225.     AND    AL,ZEROEFF             ;AND MASK OFF THE HI NIBBLE
  226.     CALL    PROC_LOW_NIBBLE          ;AND GET THE ASCII VALUE OF IT
  227.     MOV    BYTE PTR [LOW_NIBBLE_AH],AL     ;THEN STORE IT
  228.     XOR    AX,AX                 ;CLEAR THE AX REGISTER AGAIN
  229.     MOV    AL,BYTE PTR [STORE_AH]         ;AND GET THE AH REG VALUE AGAIN
  230.     CALL    PROC_HI_NIBBLE             ;PROCESS FOR THE HI NIBBLE
  231.     CALL    PROC_LOW_NIBBLE          ;TO THE SAME JOB AGAIN
  232.     MOV    BYTE PTR [HI_NIBBLE_AH],AL     ;AND STORE IT
  233.     XOR    AX,AX                 ;CLEAR AX AGAIN
  234.     RET                     ;AND RETURN TO CALLER
  235. HEXDEC ENDP
  236.  
  237. PROC_LOW_NIBBLE PROC NEAR
  238.     DAA                      ;IF >9 THEN ADD 06
  239.     PUSH    AX                  ;WHICH SET AUX_CARRY_FLAG
  240.     LAHF                      ;SO LOAD THE FLAGS TO CHECK
  241.     AND    AH,10                  ;MASK ALL EXCEPT AUX_FLAG
  242.     CMP    AH,10                  ;CHECK FOR FLAG SET
  243.     JNZ    OVER1                  ;IF IT ISN'T SET JUST ADD 30H
  244.     POP    AX                  ;RESTORE THE SAVED DATA
  245.     ADD    AL,31                  ;ELSE IT'S SET, ADD 31 [ >9 ]
  246.     JMP    OVER2                  ;DON'T ADD AGAIN, JUMP OVER IT
  247. OVER1:    POP    AX                  ;ADDING 30H IS FOR NUMBERS
  248.     ADD    AL,30                  ;ADDING 31H IS FOR  A through F
  249. OVER2:    RET                      ;RETURN TO CALLER
  250. PROC_LOW_NIBBLE ENDP
  251.  
  252. PROC_HI_NIBBLE PROC NEAR
  253.     XOR    CX,CX                  ;CLEAR CX, JUST TO BE SURE
  254.     AND    AL,EFFZERO              ;MASK OFF LEAST SIGNIFICANT NIBB
  255.     MOV    CL,04                  ;HOW MANY TIMES TO SHIFT?
  256.     SHR    AL,CL                  ;THEN MOVE MOST SN TO LEAST SN
  257.     RET                      ;RETURN TO CALLER
  258. PROC_HI_NIBBLE ENDP
  259.  
  260. SEND_REPORT PROC NEAR
  261.     MOV    SI,OFFSET REPORT_1          ;POINT TO STRING
  262.     XOR    CX,CX                  ;CLEAR CX, JUST TO BE SURE
  263.     MOV    CL,3DH                  ;HOW MANY CHARACTERS TO SEND
  264. NEXT:    LODSB                      ;LOAD INTO AL POINTED BY SI
  265.     MOV    AH,0EH                  ;MOVE VIDEO FUNCTION INTO AH
  266.     MOV    BH,00                  ;WRITE TTY TO PAGE ZERO(0)
  267.     INT    10                  ;DO IT
  268.     LOOP    NEXT                  ;LOOP IS, CX=CX-1 TILL CX=0000
  269.     RET                      ;WHEN CX=0000, RETURN
  270. SEND_REPORT ENDP
  271.  
  272.  
  273. CODESEG ENDS
  274.  
  275.     END    MAIN
  276.           ;LOOP IS, CX=CX-1 TILL CX=00